
package com.hlkj.pay.service.order.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.util.List;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.pojo.PageResult;
import com.hlkj.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelComplaintOrderContext;
import com.hlkj.pay.app.merchant.ext.impl.wxpay.dto.WxComplaintHistoryDto;
import com.hlkj.pay.common.CommonResultCode;
import com.hlkj.pay.common.constants.RedisConstants;
import com.hlkj.pay.dto.order.ComplaintOrderQueryDto;
import com.hlkj.pay.gateway.order.impl.ChannelComplaintGatewayImpl;
import com.hlkj.pay.infrastructure.mapper.order.OrderComplaintChannelMapper;
import com.hlkj.pay.infrastructure.mapper.order.OrderComplaintHistoryMapper;
import com.hlkj.pay.infrastructure.mapper.order.OrderComplaintMapper;
import com.hlkj.pay.infrastructure.model.order.OrderComplaintChannelDO;
import com.hlkj.pay.infrastructure.model.order.OrderComplaintDO;
import com.hlkj.pay.infrastructure.model.order.OrderComplaintHistoryDO;
import com.hlkj.pay.service.CommonSnFilterService;
import com.hlkj.pay.service.order.IOrderComplaintService;
import com.hlkj.pay.task.CommonTasks;
import com.hlkj.pay.vo.order.req.ComplaintCompleteReq;
import com.hlkj.pay.vo.order.req.ComplaintDeleteReq;
import com.hlkj.pay.vo.order.req.ComplaintReplyUserReq;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2024/11/07 10:46
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderComplaintServiceImpl extends CommonSnFilterService implements IOrderComplaintService {

    private final OrderComplaintMapper orderComplaintMapper;

    private final OrderComplaintChannelMapper orderComplaintChannelMapper;

    private final OrderComplaintHistoryMapper orderComplaintHistoryMapper;

    private final ChannelComplaintGatewayImpl channelComplaintGateway;

    private final CommonTasks commonTasks;

    @Override
    public CommonResult<Void> addOrderComplaint(OrderComplaintDO orderComplaintDO) {
        orderComplaintMapper.insert(orderComplaintDO);
        return CommonResult.success();
    }

    @Override
    public PageResult<OrderComplaintDO> queryPage(ComplaintOrderQueryDto complaintOrderQueryDto) {
        // sycnComplaint();
        complaintOrderQueryDto.setSortingFields("status+,create_time-");
        LambdaQueryWrapper<OrderComplaintDO> queryWrapper = buildWrapper(complaintOrderQueryDto);
        // 过滤支付宝渠道
        List<OrderComplaintChannelDO> zfbChannels = orderComplaintChannelMapper.selectList(OrderComplaintChannelDO::getType,2);
        commonTasks.sycnComplaint(zfbChannels);

        return orderComplaintMapper.selectPage(complaintOrderQueryDto,queryWrapper);
    }

    @Override
    public List<OrderComplaintDO> queryList(ComplaintOrderQueryDto complaintOrderQueryDto) {
        LambdaQueryWrapper<OrderComplaintDO> queryWrapper = buildWrapper(complaintOrderQueryDto);
        queryWrapper.orderByAsc(OrderComplaintDO::getStatus).orderByDesc(OrderComplaintDO::getCreateTime);
        List<OrderComplaintDO> list = orderComplaintMapper.selectList(queryWrapper);
        return list;
    }


    @Override
    public OrderComplaintDO queryDetail(Long id) {
        OrderComplaintDO orderComplaintDO = orderComplaintMapper.selectById(id);
        return orderComplaintDO;
    }

    @Override
    @Cacheable(value = RedisConstants.COMPLAINT_ORDER_INFO, key = "#complaintId", unless = "#result == null")
    public OrderComplaintDO queryDetailByComplaintId(String complaintId) {
        return orderComplaintMapper.selectOne(OrderComplaintDO::getComplaintId,complaintId);
    }

    @Override
    public OrderComplaintDO queryDetailAndSync(Long id) {
        OrderComplaintDO orderComplaintDO = orderComplaintMapper.selectById(id);
        commonTasks.complaintSyncData(orderComplaintDO,null,false);
        return orderComplaintDO;
    }



    @Override
    public CommonResult<Void> updateOrderComplaint(OrderComplaintDO complaintDO) {
        try {
            if (complaintDO.getId() == null) {
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
            }
            OrderComplaintDO orderComplaintDO = queryDetail(complaintDO.getId());
            if (orderComplaintDO == null) {
                return CommonResult.error(CommonResultCode.DATA_NOT_EXIST);
            }
            orderComplaintMapper.updateById(complaintDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updateOrderComplaint error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }

    }

    @Override
    public CommonResult<Void> delOrderComplaint(Long id) {
        try {
            if (id == null) {
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
            }
            OrderComplaintDO orderComplaintDO = queryDetail(id);
            if (orderComplaintDO == null) {
                return CommonResult.error(CommonResultCode.DATA_NOT_EXIST);
            }
            orderComplaintMapper.deleteById(id);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("delOrderComplaint error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public OrderComplaintDO selectOne(ComplaintOrderQueryDto complaintOrderQueryDto) {
        return orderComplaintMapper.selectOne(buildWrapper(complaintOrderQueryDto));
    }

    @Override
    public CommonResult<Void> replyUser(ComplaintReplyUserReq complaintOrderUserReq) {

        List<String> complaintIds = complaintOrderUserReq.getId();
        if( StrUtil.isEmpty(complaintOrderUserReq.getContent()) || CollUtil.isEmpty(complaintIds)){
            return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
        }
        // 单条抛异常 批量不管
        if(complaintIds.size() == 1){
            OrderComplaintDO orderComplaintDO = queryDetail(Long.valueOf(complaintIds.get(0)));
            if(orderComplaintDO != null){
                OrderComplaintChannelDO orderComplaintChannelDO = orderComplaintChannelMapper.selectById(orderComplaintDO.getChannelId());
                ChannelComplaintOrderContext channelComplaintOrderContext = new ChannelComplaintOrderContext();
                channelComplaintOrderContext.setOrderComplaintChannelDO(orderComplaintChannelDO);
                channelComplaintOrderContext.setOrderComplaintDO(orderComplaintDO);
                channelComplaintOrderContext.setContent(complaintOrderUserReq.getContent());
                channelComplaintOrderContext.setImgUrls(complaintOrderUserReq.getImgUrls());
                channelComplaintOrderContext.setType(complaintOrderUserReq.getProcessCode());
                channelComplaintOrderContext.setReplyType(complaintOrderUserReq.getReplyType());
                channelComplaintOrderContext.setProcessStatus(true);
                channelComplaintGateway.replyUser(channelComplaintOrderContext);
                if(!channelComplaintOrderContext.isProcessStatus()){
                    return CommonResult.error(0, channelComplaintOrderContext.getRemark());
                }
            }
        }else{
            // 异步批量
            for(String id:complaintIds){
                OrderComplaintDO orderComplaintDO = queryDetail(Long.valueOf(id));
                if(orderComplaintDO != null){
                    commonTasks.complaintBatchReplyUser(orderComplaintDO,complaintOrderUserReq);
                }
            }
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult<Void> complete(ComplaintCompleteReq complaintCompleteReq) {

        List<String> complaintIds = complaintCompleteReq.getId();
        if( CollUtil.isEmpty(complaintIds)){
            return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
        }
        // 单条抛异常 批量不管
        if(complaintIds.size() == 1){
            OrderComplaintDO orderComplaintDO = queryDetail(Long.valueOf(complaintIds.get(0)));
            if(orderComplaintDO != null){
                OrderComplaintChannelDO orderComplaintChannelDO = orderComplaintChannelMapper.selectById(orderComplaintDO.getChannelId());
                ChannelComplaintOrderContext channelComplaintOrderContext = new ChannelComplaintOrderContext();
                channelComplaintOrderContext.setOrderComplaintChannelDO(orderComplaintChannelDO);
                channelComplaintOrderContext.setOrderComplaintDO(orderComplaintDO);
                channelComplaintOrderContext.setContent(complaintCompleteReq.getContent());
                channelComplaintOrderContext.setType(complaintCompleteReq.getType());
                channelComplaintOrderContext.setImgUrls(complaintCompleteReq.getImgUrls());
                channelComplaintOrderContext.setProcessStatus(true);
                channelComplaintGateway.complete(channelComplaintOrderContext);
                // 更新协商历史
                if(CollUtil.isNotEmpty(channelComplaintOrderContext.getOrderComplaintHistoryDOList())){
                    orderComplaintHistoryMapper.insertBatch(channelComplaintOrderContext.getOrderComplaintHistoryDOList());
                }

            }
        }else{
            // 异步批量
            for(String id:complaintIds){
                OrderComplaintDO orderComplaintDO = queryDetail(Long.valueOf(id));
                if(orderComplaintDO != null){
                    commonTasks.complaintBatchComplete(orderComplaintDO,complaintCompleteReq);
                }
            }
        }
        return CommonResult.success();
    }

    @Override
    public PageResult<WxComplaintHistoryDto> queryHistoryPage(ComplaintOrderQueryDto complaintOrderQueryDto) {
        Long id = complaintOrderQueryDto.getId();
        OrderComplaintDO orderComplaintDO = queryDetail(id);
        OrderComplaintChannelDO orderComplaintChannelDO = orderComplaintChannelMapper.selectById(orderComplaintDO.getChannelId());
        if(orderComplaintChannelDO == null){
            log.error("投诉列表 queryHistoryPage channelId 不存在");
            return null;
        }
        ChannelComplaintOrderContext channelComplaintOrderContext = new ChannelComplaintOrderContext();
        channelComplaintOrderContext.setOrderComplaintChannelDO(orderComplaintChannelDO);
        channelComplaintOrderContext.setOrderComplaintDO(orderComplaintDO);
        channelComplaintOrderContext.setLimit(complaintOrderQueryDto.getPageSize());
        channelComplaintOrderContext.setOffset(complaintOrderQueryDto.getPageNo());
        channelComplaintOrderContext.setProcessStatus(true);
        CommonResult<PageResult<WxComplaintHistoryDto>> commonResult = channelComplaintGateway.queryHistoryPage(channelComplaintOrderContext);
        return commonResult.getData();
    }

    @Override
    public CommonResult<Void> delBatch(ComplaintDeleteReq complaintDeleteReq) {
        if(CollUtil.isNotEmpty(complaintDeleteReq.getId())){
            orderComplaintMapper.deleteBatchIds(complaintDeleteReq.getId());
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult<Void> refund(ComplaintCompleteReq complaintCompleteReq) {
        List<String> complaintIds = complaintCompleteReq.getId();
        if( CollUtil.isEmpty(complaintIds)){
            return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
        }
        // 单条抛异常 批量不管
        boolean isThrow = false;
        if(complaintIds.size() == 1){
            isThrow = true;
        }
        // 判断是否批量操作
        OrderComplaintDO orderComplaintDO = null;
        for(String id:complaintIds){
            orderComplaintDO = queryDetail(Long.valueOf(id));
            if(orderComplaintDO != null){
                OrderComplaintChannelDO orderComplaintChannelDO = orderComplaintChannelMapper.selectById(orderComplaintDO.getChannelId());
                ChannelComplaintOrderContext channelComplaintOrderContext = new ChannelComplaintOrderContext();
                channelComplaintOrderContext.setOrderComplaintChannelDO(orderComplaintChannelDO);
                channelComplaintOrderContext.setOrderComplaintDO(orderComplaintDO);
                channelComplaintOrderContext.setProcessStatus(true);
                channelComplaintGateway.refund(channelComplaintOrderContext);
                if(!channelComplaintOrderContext.isProcessStatus() && isThrow){
                    CommonResult.error(0,channelComplaintOrderContext.getRemark());
                }
            }
        }

        return CommonResult.success();
    }

    @Override
    public Integer countBySn(ComplaintOrderQueryDto complaintOrderQueryDto) {
        return orderComplaintMapper.selectCount(buildWrapper(complaintOrderQueryDto)).intValue();
    }

    @Override
    public PageResult<OrderComplaintHistoryDO> queryComplaintHistoryPage(ComplaintOrderQueryDto complaintOrderQueryDto) {
        filterSn(complaintOrderQueryDto);
        LambdaQueryWrapperX<OrderComplaintHistoryDO> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.eqIfPresent(OrderComplaintHistoryDO::getComplaintId, complaintOrderQueryDto.getComplaintId());
        return orderComplaintHistoryMapper.selectPage(complaintOrderQueryDto,queryWrapper);
    }

    /**
     * 查询条件封装
     *
     * @param complaintOrderQueryDto
     * @return
     */
    LambdaQueryWrapper<OrderComplaintDO> buildWrapper(ComplaintOrderQueryDto complaintOrderQueryDto) {
        filterSn(complaintOrderQueryDto);
        LambdaQueryWrapperX<OrderComplaintDO> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.eqIfPresent(OrderComplaintDO::getPayOrderNo, complaintOrderQueryDto.getPayOrderNo());
        queryWrapper.eqIfPresent(OrderComplaintDO::getMchOrderNo, complaintOrderQueryDto.getMchOrderNo());
        queryWrapper.eqIfPresent(OrderComplaintDO::getComplaintId, complaintOrderQueryDto.getComplaintId());
        queryWrapper.eqIfPresent(OrderComplaintDO::getWxOrderNo, complaintOrderQueryDto.getWxOrderNo());
        queryWrapper.eqIfPresent(OrderComplaintDO::getChannelCode, complaintOrderQueryDto.getChannelCode());
        queryWrapper.eqIfPresent(OrderComplaintDO::getProviderCode, complaintOrderQueryDto.getProviderCode());
        queryWrapper.eqIfPresent(OrderComplaintDO::getStatus, complaintOrderQueryDto.getStatus());
        queryWrapper.eqIfPresent(OrderComplaintDO::getType, complaintOrderQueryDto.getType());
        queryWrapper.eqIfPresent(OrderComplaintDO::getSn, complaintOrderQueryDto.getSn());
        queryWrapper.inIfPresent(OrderComplaintDO::getSn, complaintOrderQueryDto.getSnList());
        queryWrapper.eqIfPresent(OrderComplaintDO::getAppId, complaintOrderQueryDto.getAppId());
        queryWrapper.eqIfPresent(OrderComplaintDO::getPhone, complaintOrderQueryDto.getPhone());
        queryWrapper.geIfPresent(OrderComplaintDO::getCreateTime, complaintOrderQueryDto.getStartQueryTime());
        queryWrapper.leIfPresent(OrderComplaintDO::getCreateTime, complaintOrderQueryDto.getEndQueryTime());
        return queryWrapper;
    }
}
